package com.hsy.order.utils

import android.annotation.SuppressLint
import android.util.Log
import java.nio.charset.Charset
import java.util.*

/**
 * 蓝牙打印工具
 * Created on 2018/4/27.
 *
 * @author Yang
 */
object BluetoothPrintFormatUtil {

    /**
     * 复位打印机
     */
    val RESET = byteArrayOf(0x1b, 0x40)

    /**
     * 左对齐
     */
    val ALIGN_LEFT = byteArrayOf(0x1b, 0x61, 0x00)

    /**
     * 中间对齐
     */
    val ALIGN_CENTER = byteArrayOf(0x1b, 0x61, 0x01)

    /**
     * 右对齐
     */
    val ALIGN_RIGHT = byteArrayOf(0x1b, 0x61, 0x02)

    /**
     * 选择加粗模式
     */
    val BOLD = byteArrayOf(0x1b, 0x45, 0x01)

    /**
     * 取消加粗模式
     */
    val BOLD_CANCEL = byteArrayOf(0x1b, 0x45, 0x00)

    /**
     * 宽高加倍
     */
    val DOUBLE_HEIGHT_WIDTH = byteArrayOf(0x1d, 0x21, 0x11)

    /**
     * 宽加倍
     */
    val DOUBLE_WIDTH = byteArrayOf(0x1d, 0x21, 0x10)

    /**
     * 高加倍
     */
    val DOUBLE_HEIGHT = byteArrayOf(0x1d, 0x21, 0x01)

    /**
     * 字体不放大
     */
    val NORMAL = byteArrayOf(0x1d, 0x21, 0x00)

    /**
     * 设置默认行间距
     */
    val LINE_SPACING_DEFAULT = byteArrayOf(0x1b, 0x32)

    /**
     * 打印纸一行最大的字节
     */
    private val LINE_BYTE_SIZE = 32
    /**
     * 分隔符
     */
    private const val SEPARATOR = "$"

    private val sb = StringBuffer()

    /**
     * 排版居中标题
     *
     * @param title 标题文字
     * @return 排版好的文字
     */
    fun printCenter(title: String, isDouble: Boolean): String {
        sb.delete(0, sb.length)
        val max = if (isDouble) LINE_BYTE_SIZE / 2 else LINE_BYTE_SIZE
        for (i in 0 until (max - getBytesLength(title)) / 2) sb.append(" ")
        sb.append(title)
        sb.append("\n")
        return sb.toString()
    }

    /**
     * 打印分割线
     *
     * @return 分割线
     */
    fun printSeparator(): String {
        sb.delete(0, sb.length)
        for (i in 0 until LINE_BYTE_SIZE) sb.append("-")
        return sb.toString()
    }

    /**
     * 排版带分割线的居中内容
     *
     * @return 分割线
     */
    fun printCenterWithSeparator(msg: String): String {
        sb.delete(0, sb.length)
        val separatorLength = (LINE_BYTE_SIZE - getBytesLength(msg)) / 2
        for (i in 0 until separatorLength) sb.append("-")
        sb.append(msg)
        for (i in 0 until separatorLength) sb.append("-")
        return sb.toString()
    }

    /**
     * 排版居中内容(以':'对齐)
     *
     *
     * 例：姓名：李白
     * 病区：5A病区
     * 住院号：11111
     *
     * @param middleMsgMap 居中的内容
     * @return 排版好的文字
     */
    fun printMiddleMsg(middleMsgMap: LinkedHashMap<String, String>): String {
        sb.delete(0, sb.length)
        val separated = ":"
        val leftLength = (LINE_BYTE_SIZE - getBytesLength(separated)) / 2
        for ((key, value) in middleMsgMap) {
            for (i in 0 until leftLength - getBytesLength(key)) {
                sb.append(" ")
            }
            sb.append("$key：$value")
        }
        return sb.toString()
    }

    /**
     * 排版左右对称内容(以':'对齐)
     *
     *
     * 例：姓名：李白	住院号：111111
     * 病区：5A病区	     科室：五官科
     * 体重：130kg
     *
     * @param leftMsgMap  左边部分要打印内容	左边内容大小可大于右边内容大小  反之右边过大时会忽略内容
     * @param rightMsgMap 右边部分要打印内容
     * @return 排版好的文字
     */
    fun printSymmetryMSG(leftMsgMap: LinkedHashMap<String, String>, rightMsgMap: LinkedHashMap<String, String>): String {
        sb.delete(0, sb.length)
        val leftPrefixLength = getMaxLength(leftMsgMap.keys.toTypedArray())
        val rightValueLength = getMaxLength(rightMsgMap.values.toTypedArray())
        val rightMsgKeys = rightMsgMap.keys.toTypedArray()
        var position = 0
        for ((leftMsgPrefix, leftMsgValue) in leftMsgMap) {
            for (leftI in 0 until leftPrefixLength - getBytesLength(leftMsgPrefix)) {
                sb.append(" ")
            }
            val leftMsg = "$leftMsgPrefix：$leftMsgValue"
            sb.append(leftMsg)

            if (position > rightMsgKeys.size - 1)
                continue
            val leftLength = leftPrefixLength + getBytesLength("：$leftMsgValue")
            val rightMsgPrefix = rightMsgKeys[position] + "："
            val rightLength = getBytesLength(rightMsgPrefix) + rightValueLength
            val rightMsgValue = rightMsgMap[rightMsgKeys[position]]

            for (middle in 0 until LINE_BYTE_SIZE - leftLength - rightLength) {
                sb.append(" ")
            }
            sb.append(rightMsgPrefix)
            sb.append(rightMsgValue)
            position++
        }
        return sb.toString()
    }

    /**
     * 排版左右两列内容
     *
     * @param content 需要排版内容 $分割
     * @return 排版好的文字
     */

    fun printTwoRow(content: ArrayList<String>, isDouble: Boolean): String {
        sb.delete(0, sb.length)
        val max = if (isDouble) LINE_BYTE_SIZE / 2 else LINE_BYTE_SIZE
        for (index in content.indices) {
            val msg = content[index]
            if (msg.contains(SEPARATOR)) {
                val menus = msg.split("[$SEPARATOR]".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                if (menus.isNotEmpty()) {
                    sb.append(menus[0])
                    for (i in 0 until max - getBytesLength(menus[0]) - getBytesLength(menus[1])) {
                        sb.append(" ")
                    }
                    sb.append(menus[1])
                }
            } else { // 不包含分隔符 直接打印
                sb.append(msg)
            }
            sb.append("\n")
        }
        sb.delete(sb.length - 1, sb.length)

        return sb.toString()
    }

    /**
     * 打印订餐单 (左中右对称)
     *
     *
     * 例:
     * 名称           数量          金额
     * -------------一号篮子------------
     * 豆沙包          1            3.0
     * 蛋              1            1.5
     *
     * @param menuMsgMap Key为分割 Value为 菜谱字符串数组    格式为：豆沙包$数量$单价
     * @return 排版好的文字
     */
    fun printMenuMSG(menuMsgMap: LinkedHashMap<String, LinkedList<String>>): String {
        sb.delete(0, sb.length)

        var menus: Array<String>
        val menuNames = ArrayList<String>()
        val menuPrices = ArrayList<String>()
        for (strList in menuMsgMap.values) {
            for (str in strList) {
                if (str.contains(SEPARATOR)) {
                    menus = str.split("[$SEPARATOR]".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                    if (menus.isNotEmpty()) {
                        menuNames.add(menus[0])
                        menuPrices.add(menus[2])
                    }
                }
            }
        }

        val menuNameTxt = "名称"
        val numTxt = "数量"
        val priceTxt = "金额"

        val leftPrefixLength = getMaxLength(menuNames.toTypedArray())
        var rightPrefixLength = getMaxLength(menuPrices.toTypedArray())
        if (rightPrefixLength < getBytesLength(priceTxt))
            rightPrefixLength = getBytesLength(priceTxt)

        val leftMiddleNameLength = leftPrefixLength - getBytesLength(menuNameTxt)
        sb.append(menuNameTxt)
        val middleNumTxtLength = (LINE_BYTE_SIZE - leftPrefixLength - rightPrefixLength - getBytesLength(numTxt)) / 2
        for (i in 0 until middleNumTxtLength + leftMiddleNameLength + 2) sb.append(" ")
        sb.append(numTxt)
        val middlePriceTxtLength = rightPrefixLength - getBytesLength(priceTxt)
        for (i in 0 until middleNumTxtLength + middlePriceTxtLength - 2) sb.append(" ")
        sb.append(priceTxt)
        sb.append("\n")

        Log.d("StringBuffer", sb.toString())
        for ((key, value) in menuMsgMap) {
            if ("" != key) {
                val separatorLength = (LINE_BYTE_SIZE - getBytesLength(key)) / 2
                for (i in 0 until separatorLength) sb.append("-")
                sb.append(key)
                for (i in 0 until separatorLength) sb.append("-")
            }
            for (menu in value) {
                if (menu.contains(SEPARATOR)) {
                    menus = menu.split("[$SEPARATOR]".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
                    if (menus.isNotEmpty()) {
                        sb.append(menus[0])
                        for (i in 0 until leftPrefixLength - getBytesLength(menus[0]) + middleNumTxtLength + getBytesLength(numTxt) / 2 + 1) {
                            sb.append(" ")
                        }
                        sb.append(menus[1])
                        for (i in 0 until middleNumTxtLength + getBytesLength(numTxt) / 2 + 1 - getBytesLength(menus[1]) + middlePriceTxtLength - 2) {
                            sb.append(" ")
                        }
                        sb.append(menus[2])
                    }
                } else { // 不包含分隔符 直接打印
                    for (i in 0 until LINE_BYTE_SIZE / getBytesLength(menu) - getBytesLength("\n")) {
                        sb.append(menu)
                    }
                    sb.append("\n")
                }
            }
            Log.d("StringBuffer", sb.toString())
        }
        return sb.toString()
    }

    /**
     * 获取最大长度
     *
     * @return 最大长度
     */
    private fun getMaxLength(msgs: Array<Any>): Int {
        var max = 0
        var tmp: Int
        for (oo in msgs) {
            tmp = getBytesLength(oo.toString())
            if (tmp > max) {
                max = tmp
            }
        }
        return max
    }

    /**
     * 获取数据长度
     *
     * @return 数据长度
     */
    @SuppressLint("NewApi")
    private fun getBytesLength(msg: String): Int {
        return msg.toByteArray(Charset.forName("GB2312")).size
    }

}